home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / abuse / src / endgame.c < prev    next >
C/C++ Source or Header  |  1996-04-12  |  13KB  |  520 lines

  1. #include "menu.hpp"
  2. #include "lisp.hpp"
  3. #include "game.hpp"
  4. #include "timing.hpp"
  5. #include "game.hpp"
  6. #include "id.hpp"
  7. #include "pmenu.hpp"
  8. #include "gui.hpp"
  9. #include "property.hpp"
  10. #include "dev.hpp"
  11. #include "clisp.hpp"
  12. #include "dprint.hpp"
  13. #include "jrand.hpp"
  14. #include "director.hpp"
  15. #include <math.h>
  16. #include "lisp_gc.hpp"
  17.  
  18. extern palette *old_pal;
  19.  
  20. struct mask_line
  21. {
  22.   int x,size;
  23.   ushort *remap;
  24.   uchar *light;
  25. } ;
  26.  
  27.  
  28. int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, JCFont *font, uchar *cmap, char color);
  29.  
  30. mask_line *make_mask_lines(image *mask, int map_width)
  31. {
  32.   mask_line *p=(mask_line *)jmalloc(mask->height()*sizeof(mask_line),"mask_line");
  33.   for (int y=0;y<mask->height();y++)
  34.   {
  35.     // find the start of the run..
  36.     uchar *sl=mask->scan_line(y);    
  37.     int x=0;
  38.     while (*sl==0) { sl++; x++; }
  39.     p[y].x=x;
  40.  
  41.    
  42.     // find the length of the run
  43.     int size=0; 
  44.     uchar *sl_start=sl;
  45.     while (*sl!=0 && x<mask->width()) { sl++; x++; size++; }
  46.     p[y].size=size;
  47.  
  48.     // now calculate remap for line
  49.     p[y].remap=(ushort *)jmalloc(size*2,"mask remap");
  50.     p[y].light=(uchar *)jmalloc(size,"mask light");
  51.     ushort *rem=p[y].remap;
  52.     uchar *lrem=p[y].light;
  53.     for (x=0;x<size;x++,rem++)
  54.     {
  55.       *(lrem++)=*(sl_start++);
  56. /*      if (x==size/2 || x==size/2-1 || x==size/2+1)
  57.         *rem=(int)(sqrt(0.5)*map_width/2.0);
  58.       else*/ 
  59.       if (x<=size/2)
  60.         *rem=(int)(sqrt(x/(double)(size*2.0))*map_width/2.0);
  61.       else
  62.         *rem=map_width/2-(int)(sqrt((size-x)/(double)(size*2.0))*map_width/2.0);
  63.  
  64. //      (int)(mask->width()-(sqrt((size-x)/(double)size)*map_width/2.0)+mask->width()/2);
  65.     }
  66.   }
  67.   return p;
  68. }
  69.  
  70.  
  71. void scan_map(image *screen, int sx, int sy, image *im1, image *im2, int fade256, long *paddr, mask_line *p, int mask_height, 
  72.           int xoff, int coff)
  73. {  
  74.   int x1=10000,x2=0;
  75.   int iw=im1->width();  
  76.   ushort r,co,off,cc;
  77.   int y=0;
  78.   uchar *l;
  79.  
  80.   for (;y<mask_height;y++)
  81.   {
  82.     mask_line *n=p+y;
  83.     uchar *sl=screen->scan_line(y+sy)+sx+n->x;
  84.     uchar *sl2=im1->scan_line(y);
  85.     uchar *sl3=im2->scan_line(y);
  86.     l=n->light;
  87.     ushort *rem=n->remap;
  88.     if (sx+n->x<x1) x1=sx+n->x;    
  89.     int x=0;
  90.     for (;x<n->size;x++,sl++,rem++,l++)   
  91.     {
  92.       r=*rem;
  93.  
  94.       off=(r+xoff);
  95.       if (off>=iw) off-=iw;
  96.  
  97.       long p1=*(paddr+sl2[off]);
  98.       long p2=*(paddr+sl3[off]);
  99.  
  100.       int r1=p1>>16,g1=(p1>>8)&0xff,b1=p1&0xff;
  101.       int r2=p2>>16,g2=(p2>>8)&0xff,b2=p2&0xff;
  102.       int r3=r1+(r2-r1)*fade256/256,
  103.           g3=g1+(g2-g1)*fade256/256,
  104.           b3=b1+(b2-b1)*fade256/256;
  105.  
  106.       uchar c=color_table->lookup_color(r3>>3,g3>>3,b3>>3);
  107.                 
  108.       *sl=*(white_light+((*l)/2+28+jrand()%4)*256+c); 
  109.       
  110.     }
  111.     if (sx+n->x+x>x2) x2=sx+n->x+x;
  112.     
  113.   }
  114.   screen->add_dirty(x1,sy,x2,sy+mask_height-1);
  115.  
  116. }
  117.  
  118.  
  119.  
  120. void fade_in(image *im, int steps);
  121. void fade_out(int steps);
  122.  
  123. class ex_char { 
  124.   public :
  125.   uchar frame,char_num;
  126.   int x,y;
  127.   ex_char *next; 
  128.   ex_char (int X, int Y, int Frame, int Char_num, ex_char *Next) { x=X; y=Y; frame=Frame; char_num=Char_num; next=Next; }
  129. } ;
  130.  
  131. void scale_put      (image *im, image *screen, int x, int y, short new_width, short new_height);
  132. void scale_put_trans(image *im, image *screen, int x, int y, short new_width, short new_height);
  133.  
  134. void show_end2()
  135. {
  136.   int i;
  137.   int planet=cash.reg("art/endgame.spe","planet",SPEC_IMAGE,1);
  138.   int planet2=cash.reg("art/endgame.spe","dead_planet",SPEC_IMAGE,1);
  139.   int mask=cash.reg("art/endgame.spe","mask",SPEC_IMAGE,1);
  140.   int ship=cash.reg("art/endgame.spe","ship",SPEC_IMAGE,1);
  141.  
  142.  
  143.   int explo_snd=lnumber_value(symbol_value(make_find_symbol("P_EXPLODE_SND")));
  144.   int space_snd=lnumber_value(symbol_value(make_find_symbol("SPACE_SND")));
  145.   int zip_snd=lnumber_value(symbol_value(make_find_symbol("SHIP_ZIP_SND")));
  146.   
  147.  
  148.   mask_line *p=make_mask_lines(cash.img(mask),cash.img(planet)->width());  
  149.  
  150.   int explo_frames1[8],explo_frames2[7];
  151.  
  152.   for (i=0;i<8;i++)
  153.   { char nm[100]; sprintf(nm,"small_wite%04d.pcx",i+1);
  154.     explo_frames1[i]=cash.reg("art/exp1.spe",nm,SPEC_CHARACTER,1);
  155.   }
  156.  
  157.   for (i=0;i<7;i++)
  158.   { char nm[100]; sprintf(nm,"small_fire%04d.pcx",i+1);
  159.     explo_frames2[i]=cash.reg("art/exp1.spe",nm,SPEC_CHARACTER,1);
  160.   }
  161.  
  162.   int eoff=0,coff=0;
  163.  
  164.   int ex=xres/2-cash.img(mask)->width()/2;
  165.   int ey=yres/2-cash.img(mask)->height()/2;
  166.   fade_out(16);
  167.  
  168.   image blank(2,2); blank.clear();
  169.   eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  170.  
  171.  
  172.   screen->clear();
  173.   int c[4]={pal->find_closest(222,222,22),
  174.         pal->find_closest(200,200,200),
  175.         pal->find_closest(100,100,100),
  176.         pal->find_closest(64,64,64)};
  177.   ushort sinfo[800*3],*si;
  178.  
  179.   for (si=sinfo,i=0;i<800;i++)
  180.   {
  181.     *(si++)=jrand()%320; 
  182.     *(si++)=jrand()%200;     
  183.     *(si++)=c[jrand()%4];     
  184.     screen->putpixel(si[-3],si[-2],si[-1]);
  185.   }
  186.   long paddr[256];
  187.   if (old_pal)
  188.   {
  189.     for (i=0;i<256;i++) 
  190.       paddr[i]=(old_pal->red(i)<<16)|(old_pal->green(i)<<8)|(old_pal->blue(i)); 
  191.   }
  192.   else
  193.   {
  194.     for (i=0;i<256;i++) 
  195.       paddr[i]=(pal->red(i)<<16)|(pal->green(i)<<8)|(pal->blue(i));
  196.   }
  197.  
  198.   int dx=(xres+1)/2-320/2,dy=(yres+1)/2-200/2;
  199.  
  200.  
  201.   scan_map(screen,ex,ey,cash.img(planet),cash.img(planet2),0,paddr,p,cash.img(mask)->height(),eoff,coff);      
  202.   image *tcopy=cash.img(planet)->copy();
  203.   fade_in(NULL,32);
  204.  
  205.   time_marker old_time;
  206.  
  207.  
  208.   
  209.   for (i=0;i<80;)
  210.   {
  211.     time_marker new_time;    
  212.     if (new_time.diff_time(&old_time)>0.1)
  213.     {
  214.       if ((i%10)==0 && (sound_avail&SFX_INITIALIZED))
  215.         cash.sfx(space_snd)->play(64);
  216.  
  217.       old_time.get_time();
  218.       screen->clear();
  219.       int j;
  220.       for (si=sinfo,j=0;j<800;j++,si+=3)
  221.         screen->putpixel(dx+si[0],dy+si[1],si[2]);
  222.  
  223.       if (i>=30 && i<=37)
  224.       {
  225.     cash.img(planet)->put_image(tcopy,0,0);
  226.     cash.fig(explo_frames1[i-30])->forward->put_image(tcopy,100,50);
  227.         scan_map(screen,ex,ey,tcopy,
  228.            cash.img(planet2),
  229.            0,paddr,
  230.            p,cash.img(mask)->height(),eoff,coff);      
  231.       } 
  232.       else
  233.         scan_map(screen,ex,ey,cash.img(planet),
  234.            cash.img(planet2),
  235.            0,paddr,
  236.            p,cash.img(mask)->height(),eoff,coff);      
  237.       if (i>38)
  238.       {
  239.     int t=i-38;
  240.     image *s=cash.img(ship);
  241.     int nw=s->width()*(t+2)/16,
  242.         nh=s->height()*(t+2)/16;
  243.  
  244.  
  245.         scale_put_trans(s,screen,ex-(i-38)*5,ey+cash.img(mask)->height()/2+t*4,nw,nh);
  246.     if (i==77)
  247.       if (sound_avail&SFX_INITIALIZED)
  248.             cash.sfx(zip_snd)->play(127);
  249.       }
  250.         
  251.       eoff+=2; if (eoff>=320) eoff-=320;
  252.       coff+=1; if (coff>=320) coff-=320;      
  253.       eh->flush_screen();
  254.       i++;
  255.     }
  256.   }
  257.   delete tcopy;
  258.  
  259.  
  260.   ex_char *clist=NULL;
  261.   for (i=0;i<200;)
  262.   {
  263.     time_marker new_time;
  264.     if (new_time.diff_time(&old_time)>0.1)
  265.     {
  266.       if ((i%10)==0 && (sound_avail&SFX_INITIALIZED))
  267.         cash.sfx(space_snd)->play(64);
  268.  
  269.       old_time.get_time();
  270.       screen->clear();
  271.       int j;
  272.       for (si=sinfo,j=0;j<800;j++,si+=3)
  273.         screen->putpixel(dx+si[0],dy+si[1],si[2]);
  274.  
  275.       
  276.       scan_map(screen,ex,ey,cash.img(planet),
  277.            cash.img(planet2),i*256/200,paddr,p,cash.img(mask)->height(),eoff,coff);      
  278.  
  279.       eoff+=2; if (eoff>=320) eoff-=320;
  280.       coff+=1; if (coff>=320) coff-=320;      
  281.  
  282.       i++;
  283.       if (i<150 || (i<170 && ((i-149)%2)==0) || (i<180 && ((i-149)%4)==0) || (i<190 && ((i-149)%8)==0))
  284.       {
  285.         clist=new ex_char(ex+jrand()%(cash.img(mask)->width()-cash.img(mask)->width()/3),
  286.             ey+jrand()%(cash.img(mask)->height()-cash.img(mask)->height()/3),0,1,clist);
  287.     if (sound_avail&SFX_INITIALIZED)
  288.           cash.sfx(explo_snd)->play(127);
  289.       }
  290.  
  291. //      clist=new ex_char(ex+jrand()%(cash.img(mask)->width(),
  292. //            ey+jrand()%(cash.img(mask)->height(),0,1,clist);
  293.  
  294.       ex_char *c=clist,*last=NULL;
  295.       for (;c;)
  296.       {
  297.     c->frame++;
  298.     if (c->frame>6)
  299.     {
  300.       ex_char *d=c;
  301.       if (last) last->next=c->next;
  302.       else clist=c->next;
  303.       c=c->next;
  304.       delete d;
  305.     } else
  306.     { 
  307.       last=c; 
  308.       if (c->char_num)    
  309.         cash.fig(explo_frames2[c->frame])->forward->put_image(screen,c->x,c->y);      
  310.  
  311.       c->x-=3;
  312.       c=c->next; 
  313.     }      
  314.       }
  315.  
  316.       eh->flush_screen();
  317.  
  318.     }
  319.  
  320.  
  321.   }
  322.   while (clist) { ex_char *p=clist; clist=clist->next; delete p; }
  323.  
  324.   screen->clear();
  325.   int j;
  326.   for (si=sinfo,j=0;j<800;j++,si+=3)
  327.     screen->putpixel(si[0],si[1],si[2]);
  328.  
  329.   event ev;
  330.   i=0;
  331.   do
  332.   {
  333.     time_marker new_time;
  334.     if (new_time.diff_time(&old_time)>0.1)
  335.     {
  336.       if ((i%10)==0 && (sound_avail&SFX_INITIALIZED))
  337.         cash.sfx(space_snd)->play(64);
  338.  
  339.       old_time.get_time();
  340.       scan_map(screen,ex,ey,cash.img(planet),
  341.            cash.img(planet2),
  342.            256,paddr,
  343.            p,cash.img(mask)->height(),eoff,coff);      
  344.       eoff+=2; if (eoff>=320) eoff-=320;
  345.       coff+=1; if (coff>=320) coff-=320;      
  346.       eh->flush_screen();
  347.       i++;
  348.     }
  349.     
  350.     if (eh->event_waiting())
  351.       eh->get_event(ev);
  352.  
  353.   } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
  354.  
  355.  
  356.   uchar cmap[32];
  357.   for (i=0;i<32;i++)
  358.     cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
  359.  
  360.   void *end_plot=symbol_value(make_find_symbol("plot_end"));
  361.  
  362.  
  363.   time_marker start;
  364.  
  365.   ev.type=EV_SPURIOUS;
  366.   for (i=0;i<320 && ev.type!=EV_KEY;i++)
  367.   {
  368.     screen->clear();
  369.     int j;
  370.     for (si=sinfo,j=0;j<800;j++,si+=3)
  371.       screen->putpixel(dx+si[0],dy+si[1],si[2]);
  372.  
  373.     scan_map(screen,ex,ey,cash.img(planet),
  374.          cash.img(planet2),
  375.          256,paddr,
  376.          p,cash.img(mask)->height(),eoff,coff);      
  377.     text_draw(205-i,dx+10,dy,dx+319-10,dy+199,lstring_value(end_plot),eh->font(),cmap,eh->bright_color());
  378.     eh->flush_screen();
  379.     time_marker now; while (now.diff_time(&start)<0.18) now.get_time(); start.get_time();
  380.  
  381.     while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
  382.   }
  383.  
  384.  
  385.  
  386.   for (i=0;i<cash.img(mask)->height();i++)
  387.   {
  388.     jfree(p[i].remap);
  389.     jfree(p[i].light);
  390.   }
  391.  
  392.   jfree(p);
  393.  
  394.  
  395.   delete current_level;
  396.   current_level=NULL;
  397.  
  398.   fade_out(16);
  399.   screen->clear();
  400.  
  401.  
  402.   eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  403.   the_game->set_state(MENU_STATE);
  404. }
  405.  
  406. void show_sell(int abortable);
  407.  
  408. void share_end()
  409. {
  410.   fade_out(16);
  411.   image blank(2,2); blank.clear();
  412.   eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  413.   screen->clear();
  414.  
  415.   image *im=cash.img(cash.reg("art/endgame.spe","tbc",SPEC_IMAGE,1));
  416.  
  417.   void *to_be=symbol_value(make_find_symbol("to_be_continued"));
  418.   p_ref r1(to_be);
  419.  
  420.   void *mid_plot=symbol_value(make_find_symbol("plot_middle"));
  421.   p_ref r2(mid_plot);
  422.  
  423.  
  424.   int dx=(xres+1)/2-im->width()/2,dy=(yres+1)/2-im->height()/2;
  425.   im->put_image(screen,dx,dy);
  426.   console_font->put_string(screen,xres/2+35,yres/2+100-console_font->height()-2,
  427.                lstring_value(to_be));
  428.   fade_in(NULL,32);
  429.  
  430.   uchar cmap[32];
  431.   int i;
  432.   for (i=0;i<32;i++)
  433.     cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
  434.  
  435.   event ev; ev.type=EV_SPURIOUS;
  436.   time_marker start;
  437.   for (i=0;i<320 && ev.type!=EV_KEY;i++)
  438.   {
  439.     im->put_image(screen,dx,dy);
  440.     console_font->put_string(screen,xres/2+35,yres/2+100-console_font->height()-2,
  441.                lstring_value(to_be));
  442.  
  443.     text_draw(205-i,dx+10,dy,dx+319-10,dy+199,lstring_value(mid_plot),eh->font(),cmap,eh->bright_color());
  444.     eh->flush_screen();
  445.     time_marker now; while (now.diff_time(&start)<0.18) now.get_time(); start.get_time();
  446.     while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
  447.   }
  448.  
  449.   if (ev.type!=EV_KEY)
  450.   {
  451.     do
  452.     {
  453.       eh->flush_screen();
  454.       eh->get_event(ev);    
  455.     } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
  456.   }
  457.  
  458.   fade_out(16);
  459.   eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse  
  460.   show_sell(1);
  461.   eh->push_event(new event(ID_SHOW_SELL,NULL));
  462. }
  463.  
  464.  
  465. void show_end()
  466. {
  467.   fade_out(16);
  468.   image blank(2,2); blank.clear();
  469.   eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  470.   screen->clear();
  471.  
  472.   image *im=cash.img(cash.reg("art/endgame.spe","end.pcx",SPEC_IMAGE,1));
  473.  
  474.   int dx=(xres+1)/2-320/2,dy=(yres+1)/2-200/2;
  475.  
  476.   void *end_plot=symbol_value(make_find_symbol("plot_end"));
  477.   p_ref r2(end_plot);
  478.  
  479.  
  480.   fade_in(im,32);
  481.  
  482.   uchar cmap[32];
  483.   int i;
  484.   for (i=0;i<32;i++)
  485.     cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
  486.  
  487.   event ev; ev.type=EV_SPURIOUS;
  488.   time_marker start;
  489.   for (i=0;i<320 && ev.type!=EV_KEY;i++)
  490.   {
  491.     im->put_image(screen,dx,dy);
  492.  
  493.     text_draw(205-i,dx+10,dy,dx+319-10,dy+199,lstring_value(end_plot),eh->font(),cmap,eh->bright_color());
  494.     eh->flush_screen();
  495.     time_marker now; while (now.diff_time(&start)<0.18) now.get_time(); start.get_time();
  496.     while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
  497.   }
  498.  
  499.   if (ev.type!=EV_KEY)
  500.   {
  501.     do
  502.     {
  503.       eh->flush_screen();
  504.       eh->get_event(ev);    
  505.     } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
  506.   }
  507.  
  508.   delete current_level;
  509.   current_level=NULL;
  510.  
  511.   fade_out(16);
  512.   screen->clear();
  513.  
  514.   show_sell(1);
  515.  
  516.   eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  517.   the_game->set_state(MENU_STATE);
  518. }
  519.  
  520.